from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query
from typing import List, Dict, Any, Optional
from app.services.tencent.image_recognition import TencentImageRecognitionService
from app.services.image.processor import ImageProcessor
from app.schemas.image import (
    ImageSearchResponse, ImageUploadResponse, GroupListResponse, 
    ImageListResponse, GroupInfo, ImageDetailInfo, ImageDetailResponse
)
import logging
import time  # 添加time模块导入
import json  # 添加这行导入

router = APIRouter()
logger = logging.getLogger(__name__)

# 依赖注入
def get_image_service() -> TencentImageRecognitionService:
    return TencentImageRecognitionService()

def get_image_processor() -> ImageProcessor:
    return ImageProcessor()

# 在现有文件中添加导入
from app.services.tencent.cos_service import TencentCOSService
from app.crud.image import image_crud
from app.core.database import get_db
from sqlalchemy.orm import Session
from PIL import Image
import io
import uuid

# 添加依赖注入
def get_cos_service() -> TencentCOSService:
    return TencentCOSService()

# 修改上传接口
@router.post("/upload", response_model=ImageUploadResponse, summary="上传图片", description="上传图片到图片库和COS存储")
async def upload_image(
    file: UploadFile = File(...),
    group_id: str = "default",
    image_service: TencentImageRecognitionService = Depends(get_image_service),
    cos_service: TencentCOSService = Depends(get_cos_service),
    processor: ImageProcessor = Depends(get_image_processor),
    db: Session = Depends(get_db)
):
    """上传图片到图片库和COS存储"""
    try:
        # 读取文件内容
        contents = await file.read()
        
        # 验证图片格式
        if not processor.validate_image_format(contents):
            raise HTTPException(status_code=400, detail="不支持的图片格式")
        
        # 调整图片尺寸
        resized_image = processor.resize_image(contents)
        
        # 获取图片信息
        with Image.open(io.BytesIO(resized_image)) as img:
            width, height = img.size
            file_format = img.format.lower()
        
        # 生成entity_id
        entity_id = str(uuid.uuid4())
        pic_name = f"{entity_id}_{int(time.time())}"
        
        # 1. 上传到COS获取URL
        cos_result = cos_service.upload_image(
            image_data=resized_image,
            file_extension=file_format,
            folder=f"images/{group_id}"
        )
        
        # 2. 转换为base64并上传到TIIA
        image_base64 = processor.bytes_to_base64(resized_image)  # 正确的调用
        tiia_result = image_service.add_image_to_group(
            group_id=group_id,
            entity_id=entity_id,
            image_base64=image_base64,
            pic_name=pic_name
        )
        
        # 3. 保存到数据库
        image_data = {
            "entity_id": entity_id,
            "group_id": group_id,
            "pic_name": pic_name,
            "original_filename": file.filename,
            "cos_url": cos_result['url'],
            "cos_key": cos_result['key'],
            "file_size": len(resized_image),
            "file_type": file_format,
            "width": width,
            "height": height,
            "upload_status": "success",
            "tencent_response": json.dumps(tiia_result)
        }
        
        db_image = image_crud.create_image(db, image_data)
        
        return ImageUploadResponse(
            success=True,
            message="图片上传成功",
            entity_id=entity_id,
            pic_name=pic_name,
            url=cos_result['url'],  # 返回COS URL
            data={
                "tiia_result": tiia_result,
                "cos_result": cos_result,
                "image_id": db_image.id
            }
        )
        
    except Exception as e:
        logger.error(f"图片上传失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"图片上传失败: {str(e)}")

# 更新导入
from app.schemas.image import (
    ImageSearchResponse, ImageUploadResponse, GroupListResponse, 
    ImageListResponse, GroupInfo, ImageDetailInfo, ImageDetailResponse,
    WaterfallResponse, WaterfallImageItem, ImageSearchItem, RelatedTag  # 添加 RelatedTag
)

@router.post("/search", response_model=ImageSearchResponse, summary="以图搜图", description="上传图片搜索相似图片")
async def search_similar_images(
    file: UploadFile = File(...),
    group_id: str = "8",
    image_service: TencentImageRecognitionService = Depends(get_image_service),
    processor: ImageProcessor = Depends(get_image_processor),
    db: Session = Depends(get_db),
):
    """以图搜图 - 上传图片搜索相似图片"""
    try:
        # 读取文件内容
        contents = await file.read()
        
        # 验证图片格式
        if not processor.validate_image_format(contents):
            raise HTTPException(status_code=400, detail="不支持的图片格式")
        
        # 调整图片尺寸
        resized_image = processor.resize_image(contents)
        
        # 转换为base64
        image_base64 = processor.bytes_to_base64(resized_image)
        
        # 搜索相似图片
        result = image_service.search_image(
            image_base64=image_base64,
            group_id=group_id
        )
        
        # 转换数据格式并收集所有产品用于标签统计
        data = []
        all_products = []  # 用于标签统计的所有产品
        
        for item in result.get("ImageInfos", []) or []:
            entity_id = item.get("EntityId")
            if not entity_id:
                continue
            
            prod = product_crud.get_by_entity_id(db=db, entity_id=entity_id)
            if not prod:
                # 跳过无对应产品的数据
                continue
            
            all_products.append(prod)
            
            # 解析产品标签为数组格式
            parsed_tags = []
            if prod.product_tags:
                try:
                    # 尝试解析JSON格式的标签
                    if prod.product_tags.startswith('[') or prod.product_tags.startswith('{'):
                        product_tag_list = json.loads(prod.product_tags)
                        if isinstance(product_tag_list, list):
                            parsed_tags = [str(tag).strip() for tag in product_tag_list if str(tag).strip()]
                        elif isinstance(product_tag_list, dict):
                            parsed_tags = [str(tag).strip() for tag in product_tag_list.values() if str(tag).strip()]
                        else:
                            parsed_tags = [str(product_tag_list).strip()]
                    else:
                        # 普通逗号分隔的标签
                        parsed_tags = [tag.strip() for tag in prod.product_tags.split(',') if tag.strip()]
                except (json.JSONDecodeError, Exception):
                    # 如果解析失败，尝试按逗号分割
                    parsed_tags = [tag.strip() for tag in prod.product_tags.split(',') if tag.strip()]
            
            data.append(ImageSearchItem(
                id=prod.id,
                entity_id=entity_id,
                pic_name=prod.product_title or "",
                cos_url=prod.cos_url or prod.image_url,
                width=prod.image_width,
                height=prod.image_height,
                file_size=None,  # 如果需要文件大小，需要在Product模型中添加此字段
                created_at=prod.created_at,
                score=item.get("Score", 0),
                product_tags=parsed_tags  # 返回解析后的标签数组
            ))
        
        # 统计相关标签
        tag_counter = {}
        for product in all_products:
            if product.product_tags:
                try:
                    # 解析产品标签（支持JSON格式）
                    if product.product_tags.startswith('[') or product.product_tags.startswith('{'):
                        product_tag_list = json.loads(product.product_tags)
                        if isinstance(product_tag_list, list):
                            tags_to_count = product_tag_list
                        elif isinstance(product_tag_list, dict):
                            tags_to_count = list(product_tag_list.values())
                        else:
                            tags_to_count = [str(product_tag_list)]
                    else:
                        # 普通逗号分隔的标签
                        tags_to_count = [tag.strip() for tag in product.product_tags.split(',') if tag.strip()]
                    
                    # 统计标签出现次数
                    for tag in tags_to_count:
                        tag = str(tag).strip()
                        if tag:
                            tag_counter[tag] = tag_counter.get(tag, 0) + 1
                except (json.JSONDecodeError, Exception):
                    # 如果解析失败，尝试按逗号分割
                    tags_to_count = [tag.strip() for tag in product.product_tags.split(',') if tag.strip()]
                    for tag in tags_to_count:
                        if tag:
                            tag_counter[tag] = tag_counter.get(tag, 0) + 1
        
        # 计算权重并排序（按出现次数降序）
        total_tags = sum(tag_counter.values())
        related_tags = []
        if total_tags > 0:
            sorted_tags = sorted(tag_counter.items(), key=lambda x: x[1], reverse=True)
            related_tags = [
                RelatedTag(
                    tag=tag,
                    count=count,
                    weight=round(count / total_tags, 4)
                )
                for tag, count in sorted_tags[:20]  # 最多返回20个相关标签
            ]
        
        return ImageSearchResponse(
            success=True,
            data=data,  # 使用 data 而不是 results
            count=len(data),
            related_tags=related_tags
        )
    except Exception as e:
        logger.error(f"图片搜索失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"图片搜索失败: {str(e)}")

@router.post("/groups/{group_id}", summary="创建图片库", description="新建图片分组")
async def create_image_group(
    group_id: str,
    group_name: str,
    image_service: TencentImageRecognitionService = Depends(get_image_service)
):
    """创建图片库 - 新建图片分组"""
    try:
        result = image_service.create_image_group(group_id, group_name)
        return {"success": True, "message": "图片库创建成功", "data": result}
        
    except Exception as e:
        logger.error(f"创建图片库失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"创建图片库失败: {str(e)}")

@router.get("/groups", response_model=GroupListResponse, summary="查询图片库列表", description="获取所有图片分组信息")
async def list_image_groups(
    offset: int = Query(0, description="起始序号"),
    limit: int = Query(10, description="返回数量，最大100"),
    group_id: Optional[str] = Query(None, description="指定图库ID"),
    image_service: TencentImageRecognitionService = Depends(get_image_service)
):
    """查询图片库列表 - 获取所有图片分组信息"""
    try:
        result = image_service.describe_groups(offset=offset, limit=limit, group_id=group_id)
        
        groups = []
        for group_data in result.get("Groups", []):
            groups.append(GroupInfo(
                group_id=group_data["GroupId"],
                group_name=group_data["GroupName"],
                brief=group_data.get("Brief"),
                create_time=group_data["CreateTime"],
                update_time=group_data["UpdateTime"],
                pic_count=group_data["PicCount"],
                max_capacity=group_data["MaxCapacity"],
                max_qps=group_data["MaxQps"],
                group_type=group_data["GroupType"]
            ))
        
        return GroupListResponse(
            success=True,
            groups=groups,
            count=len(groups)
        )
        
    except Exception as e:
        logger.error(f"查询图片库失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"查询图片库失败: {str(e)}")

@router.get("/groups/{group_id}/images/{entity_id}", response_model=ImageListResponse, summary="查询图片信息", description="获取指定图片的详细信息")
async def get_image_info(
    group_id: str,
    entity_id: str,
    pic_name: Optional[str] = Query(None, description="图片名称"),
    image_service: TencentImageRecognitionService = Depends(get_image_service)
):
    """查询图片信息 - 获取指定图片的详细信息"""
    try:
        result = image_service.describe_images(group_id=group_id, entity_id=entity_id, pic_name=pic_name)
        
        images = []
        for image_data in result.get("ImageInfos", []):
            images.append(ImageDetailInfo(
                entity_id=image_data["EntityId"],
                pic_name=image_data["PicName"],
                custom_content=image_data.get("CustomContent"),
                tags=image_data.get("Tags"),
                score=image_data.get("Score", 0)
            ))
        
        return ImageListResponse(
            success=True,
            group_id=result["GroupId"],
            entity_id=result["EntityId"],
            images=images,
            count=len(images)
        )
        
    except Exception as e:
        logger.error(f"查询图片信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"查询图片信息失败: {str(e)}")

@router.get("/groups/{group_id}/list", response_model=List[ImageDetailResponse], summary="获取图库图片列表", description="查看指定图库的所有图片")
async def list_images_in_group(
    group_id: str,
    skip: int = Query(0, description="跳过数量"),
    limit: int = Query(20, description="返回数量"),
    db: Session = Depends(get_db)
):
    """获取图库中的图片列表 - 查看指定图库的所有图片（包含URL）"""
    try:
        images = image_crud.get_images_by_group(db, group_id, skip, limit)
        return [ImageDetailResponse.from_orm(img) for img in images]
    except Exception as e:
        logger.error(f"获取图片列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取图片列表失败: {str(e)}")

# 在现有导入中添加
from fastapi import Query  # 如果还没有导入的话
# 在现有响应模型中添加
from app.schemas.image import (
    ImageSearchResponse, ImageUploadResponse, GroupListResponse, 
    ImageListResponse, GroupInfo, ImageDetailInfo, ImageDetailResponse,
    WaterfallResponse, WaterfallImageItem  # 添加这两个导入
)
# 新增：导入产品 CRUD
from app.crud.product import product_crud

# 在文件末尾添加瀑布流接口
from datetime import datetime

# 在瀑布流接口中修改
@router.get("/waterfall", response_model=WaterfallResponse, summary="获取瀑布流数据", description="分页获取图片用于前端瀑布流展示")
@router.get("/waterfall/", include_in_schema=False)
async def get_images_waterfall(
    page: int = Query(1, ge=1, description="页码，从1开始"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量，最大100"),
    group_id: Optional[str] = Query("8", description="图库ID，不传则获取所有图库的图片"),
    # 移除seed参数，改为后端自动生成
    db: Session = Depends(get_db)
):
    """获取瀑布流图片数据 - 分页获取图片用于前端瀑布流展示（现改为读取 products 表）"""
    try:
        # 强制固定 group_id 为 "8"
        group_id = "8"
        
        # 自动生成每日seed：使用当前日期作为seed
        today = datetime.now().strftime("%Y-%m-%d")
        daily_seed = f"daily_{today}"  # 例如: daily_2024-01-15
        
        # 使用每日seed进行随机排序
        products, total = product_crud.get_products_waterfall(
            db=db,
            page=page,
            page_size=page_size,
            seed=daily_seed  # 传递每日固定的seed
        )
        
        # 将 Product 映射为 WaterfallImageItem
        waterfall_items = [
            WaterfallImageItem(
                id=prod.id,
                entity_id=prod.entity_id,                    # 修改：使用产品的真实entity_id
                pic_name=prod.product_title or "",           # 使用产品标题作为名称
                cos_url=prod.cos_url or prod.image_url,      # 优先 COS URL，回退到原图 URL
                width=prod.image_width,
                height=prod.image_height,
                file_size=None,                               # products 无该字段，返回 None
                created_at=prod.created_at
            ) for prod in products
        ]
        
        has_more = page * page_size < total
        
        return WaterfallResponse(
            success=True,
            data=waterfall_items,
            total=total,
            page=page,
            page_size=page_size,
            has_more=has_more
        )
        
    except Exception as e:
        logger.error(f"获取瀑布流数据失败: {str(e)}")
        return WaterfallResponse(
            success=False,
            data=[],
            total=0,
            page=page,
            page_size=page_size,
            has_more=False
        )

